# -*- coding: utf-8 -*-
"""
Created on Tue Jul  9 09:11:12 2019

@author: MS
"""

import numpy as np
from subfuns import AnalysisData,OneHot,stdBP,accBP,initialpara
import matplotlib.pyplot as plt

#==================================================
#                表4.3 西瓜数据集3.0
#==================================================
X=[['青绿','蜷缩','浊响','清晰','凹陷','硬滑',0.697,0.460],
   ['乌黑','蜷缩','沉闷','清晰','凹陷','硬滑',0.774,0.376],
   ['乌黑','蜷缩','浊响','清晰','凹陷','硬滑',0.634,0.264],
   ['青绿','蜷缩','沉闷','清晰','凹陷','硬滑',0.608,0.318],
   ['浅白','蜷缩','浊响','清晰','凹陷','硬滑',0.556,0.215],
   ['青绿','稍蜷','浊响','清晰','稍凹','软粘',0.403,0.237],
   ['乌黑','稍蜷','浊响','稍糊','稍凹','软粘',0.481,0.149],
   ['乌黑','稍蜷','浊响','清晰','稍凹','硬滑',0.437,0.211],
   ['乌黑','稍蜷','沉闷','稍糊','稍凹','硬滑',0.666,0.091],
   ['青绿','硬挺','清脆','清晰','平坦','软粘',0.243,0.267],
   ['浅白','硬挺','清脆','模糊','平坦','硬滑',0.245,0.057],
   ['浅白','蜷缩','浊响','模糊','平坦','软粘',0.343,0.099],
   ['青绿','稍蜷','浊响','稍糊','凹陷','硬滑',0.639,0.161],
   ['浅白','稍蜷','沉闷','稍糊','凹陷','硬滑',0.657,0.198],
   ['乌黑','稍蜷','浊响','清晰','稍凹','软粘',0.360,0.370],
   ['浅白','蜷缩','浊响','模糊','平坦','硬滑',0.593,0.042],
   ['青绿','蜷缩','沉闷','稍糊','稍凹','硬滑',0.719,0.103]]
Y=np.array([1]*8+[0]*9).reshape(-1,1)
DataType=[[type(''), '青绿', '乌黑', '浅白'],    #三个取值无明显序关系 
          [type(''), '蜷缩', '稍蜷', '硬挺'],    #有序，根蒂蜷缩程度逐渐减弱
          [type(''), '沉闷', '浊响', '清脆'],    #有序，敲声清晰程度逐渐增大
          [type(''), '清晰', '稍糊', '模糊'],    #有序，纹理清晰程度逐渐减弱 
          [type(''), '凹陷', '稍凹', '平坦'],    #有序，脐部凹陷程度逐渐减弱
          [type(''), '硬滑', '软粘'],            #只有两个取值，可视为有序
          [type(0.0)], 
          [type(0.0)]]
order=[False,True,True,True,True,True,True,True]  #各个属性的取值是否含有序关系

#-------------------------原始数据转换--------------

DataType,X=AnalysisData(X,DataType)     #数值化
X=OneHot(np.array(X),DataType,order)    #对无序属性one-hot编码

#==================================================
#                神经网络训练
#==================================================
#-----初始化参数--------
m,d=X.shape      # m为样本数，d为特征数
m,l=Y.shape      # l为输出向量维数
q=5              # 隐层神经元数目
para0=initialpara(d,q,l)   # 神经网络参数：连接权重和阈值
ite=50000          # 迭代次数 

para1,erro1=stdBP(X,Y,q,para0,iteration=ite)   # 标准BP算法
para2,erro2=accBP(X,Y,q,para0,iteration=ite)   # 累积BP算法


#==================================================
#         显示训练过程中累积均方误差的变化
#==================================================
#------设置显示中文--------
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
#-------------------------
plt.figure()
plt.xlabel('迭代次数(iteration)')
plt.ylabel('累积均方误差(erro)')
plt.ylim([0,max(erro1+erro2)])
plt.scatter(range(1,ite+1),erro1,c='k',s=0.2,label='标准BP算法')
plt.scatter(range(1,ite+1),erro2,c='r',s=0.2,label='累积BP算法')
plt.title('比较标准BP和累积BP算法收敛情况')
plt.legend()
plt.show()
